/**
 * @file mainwindow.cpp
 * @brief  jisp主界面
 * 
 * Copyright (C) 2014 JakeYang <add358@gmail.com>
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QFileDialog>
#include <QMessageBox>
#include <QSerialPortInfo>

#define PARITY_NUM 6
static QString parity_list[PARITY_NUM] = {"None", "", "Even", "Odd", "Space", "Mark"};

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    m_jisp(new Jisp)
{
    ui->setupUi(this);

    /* init parity combobox */
    for (int i=0; i<PARITY_NUM; ++i) {
        ui->comboBoxParity->addItem(parity_list[i]);
    }

    /*与线程的关联*/
    connect(m_jisp, SIGNAL(send_exec_msg(int,QString)), this, SLOT(respond_exec_msg(int, QString)));
    connect(m_jisp, SIGNAL(send_flash_progress(int)), ui->progressBar, SLOT(setValue(int)));    //jisp的烧写进度与进度条关联

    /*init serialPort combobox*/
    QList<QSerialPortInfo> serialInfoList = QSerialPortInfo::availablePorts();
    QList<QSerialPortInfo>::const_iterator serialInfoList_i;
    for (serialInfoList_i = serialInfoList.constBegin(); serialInfoList_i != serialInfoList.constEnd(); ++serialInfoList_i) {
        ui->comboBoxSerialName->addItem(serialInfoList_i->portName());
    }
    QList<qint32> baudRateList = QSerialPortInfo::standardBaudRates();
    QList<qint32>::const_iterator baudRateList_i;
    for ( baudRateList_i = baudRateList.constBegin(); baudRateList_i != baudRateList.constEnd(); ++baudRateList_i ) {
        ui->comboBoxBaudrate->addItem(QString::number(*baudRateList_i));
        ui->comboBoxBaudrate->setCurrentText("9600");
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButtonFlash_clicked()
{
    if (ui->lineEditTargetFile->text().isEmpty()) {
        QMessageBox::warning(this, "烧写错误", "没有指定烧写文件");
        return;
    }
    ui->pushButtonFlash->setEnabled(false);
    ui->textBrowser->clear();

    /*设置进度条数值*/
    ui->progressBar->setValue(0);
    ui->progressBar->setMaximum(QFileInfo(ui->lineEditTargetFile->text()).size());

    m_jisp->setPortName(ui->comboBoxSerialName->currentText());
    if (  !m_jisp->open(QIODevice::ReadWrite) ) {
        QMessageBox::warning(this, "打开串口失败", "打开"+m_jisp->portName()+"失败\n请确认：1 机器上确实存在该串口\n2 用户对该串口具有可读写权限");
    }
    m_jisp->setBaudRate(ui->comboBoxBaudrate->currentText().toInt());
    m_jisp->setDataBits(Jisp::DataBits(ui->comboBoxDatabits->currentText().toInt()));
    m_jisp->setStopBits(Jisp::StopBits(ui->comboBoxStopbits->currentText().toInt()));
    m_jisp->setParity(Jisp::Parity(ui->comboBoxParity->currentIndex()));
    Jisp::FlowControl flowControl = Jisp::NoFlowControl;
    if (ui->checkBoxHardFlow->isChecked()) {
        flowControl = Jisp::HardwareControl;
    }
    if (ui->checkBoxSoftFlow->isChecked()) {
        flowControl = Jisp::SoftwareControl;
    }
    m_jisp->setFlowControl(flowControl);

    m_jisp->setFlashFile(ui->lineEditTargetFile->text());

    qDebug()<<"串口："<<m_jisp->portName();
    qDebug()<<"波特率："<<m_jisp->baudRate();
    qDebug()<<"数据位："<<m_jisp->dataBits();
    qDebug()<<"停止位："<<m_jisp->stopBits();
    qDebug()<<"检验位："<<m_jisp->parity();
    qDebug()<<"控制流："<<m_jisp->flowControl();
    qDebug()<<"将烧写的文件："<<m_jisp->flashFile();

    m_jisp->flash();        /*启动烧写线程*/
    m_jisp->close();

    ui->pushButtonFlash->setEnabled(true);
}

/**
 * @brief MainWindow::on_toolButton_clicked 启动文件对话框，选择要烧写的文件
 */
void MainWindow::on_toolButton_clicked()
{
    QString filename = QFileDialog::getOpenFileName(this, \
                                                    "选择要烧写的文件", \
                                                    ".", "target file(*.bin *.hex);;all file(*)");
    ui->lineEditTargetFile->setText(filename);
}

#define ABOUT_MSG "使用jisp软件可以向单片机烧写目标文件，方便程序使用。 "\
    "\n注意：JakeYang拥有本软件所有权，未经本人同意不得用于商业用途。"
/**
 * @brief MainWindow::on_action_about_triggered  显示本软件相关信息
 */
void MainWindow::on_action_about_triggered()
{
    QMessageBox::about(this,"关于", ABOUT_MSG);
}

/**
 * @brief MainWindow::on_exec_msg  处理jisp发送过来的执行信息
 * @param execFlag  执行类型标志
 * @param msg 输出的信息
 */
void MainWindow::respond_exec_msg(int execFlag, const QString &msg)
{
    switch (execFlag) {
    case Jisp::EXEC_ERROR:
        QMessageBox::warning(this, "执行失败", msg);
        break;
    case Jisp::GET_COMMAND:
        ui->textBrowser->append("\t\t Chip - "+ui->comboBoxTargetChip->currentText());
        ui->textBrowser->append(msg);
        break;
    default:
        break;
    }
}
